package com.zynn.api.yinian.zuul.filter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.zynn.api.yinian.zuul.constant.LoginUserConstant;
import com.zynn.api.yinian.zuul.constant.UrlConstant;
import com.zynn.common.core.dto.LoginAndRegisterResultDTO;
import com.zynn.common.pojo.result.ResultEnum;
import com.zynn.common.pojo.result.ResultUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;
import redis.clients.jedis.JedisCluster;

import javax.servlet.http.HttpServletRequest;

/**
 * filterType：返回一个字符串代表过滤器的类型，在zuul中定义了四种不同生命周期的过滤器类型，具体如下：
 * pre：路由之前
 * routing：路由之时
 * post： 路由之后
 * error：发送错误调用
 * filterOrder：过滤的顺序
 * shouldFilter：这里可以写逻辑判断，是否要过滤，本文true,永远过滤。
 * run：过滤器的具体逻辑。可用很复杂，包括查sql，nosql去判断该请求到底有没有权限访问。
 */
@Slf4j
@Component
public class TokenFilter extends ZuulFilter {

    @Autowired
    private JedisCluster jedisCluster;

    @Override
    public String filterType() {
        //表明在路由之前就执行
        return FilterConstants.PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        //表明在路由之前过滤器链中的执行顺序
        return 0;
    }

    /**
     * 表明是否需要进行路由 即是否需要执行run方法
     *
     * @return true or false
     */
    @Override
    public boolean shouldFilter() {
        //获取上下文信息
        String servletPath = RequestContext.getCurrentContext().getRequest().getServletPath();
        return !UrlConstant.matchPath(UrlConstant.PASS_SERVLET_PATHS, servletPath) && !UrlConstant.matchPath(UrlConstant.PASS_NO_AUTHS, servletPath);
    }

    /**
     * 过滤器的具体逻辑。可用很复杂，包括查sql，nosql去判断该请求到底有没有权限访问。
     */
    @Override
    public Object run() {
        RequestContext currentContext = RequestContext.getCurrentContext();
        HttpServletRequest request = currentContext.getRequest();
        //通过请求获取登录用户id
        String md5Str = request.getHeader(LoginUserConstant.USER_INFO_KEY);
        //如果获取不到用户id,直接返回错误信息
        if (StringUtils.isBlank(md5Str)) {
            currentContext.setSendZuulResponse(false);
            //返回状态为401
            currentContext.getResponse().setContentType("text/html;charset=UTF-8");
            currentContext.setResponseBody(JSON.toJSONString(ResultUtil.fail(ResultEnum.UN_AUTH)));
            currentContext.setResponseStatusCode(ResultEnum.UN_AUTH.getCode());
            return null;
        }
        String s = jedisCluster.get(md5Str);
        if (StringUtils.isBlank(s)){
            currentContext.setSendZuulResponse(false);
            currentContext.getResponse().setContentType("text/html;charset=UTF-8");
            currentContext.setResponseBody(JSON.toJSONString(ResultUtil.fail(401,"key过期")));
            currentContext.setResponseStatusCode(ResultEnum.UN_AUTH.getCode());
            return null;
        }
        LoginAndRegisterResultDTO user = JSONObject.parseObject(s, LoginAndRegisterResultDTO.class);
        //将loginUserId设置到请求head中
        currentContext.addZuulRequestHeader("loginUserId", user.getUserid().toString());
        return null;
    }


}

